package edu.whu.tao.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * <P>Web工具包</P>
 * @author 陶焕(13294175866)
 * @date 2016年3月4日 上午9:18:24
 */
public class WebUtils {

	private static Logger log = LoggerFactory.getLogger(WebUtils.class);
	
	private static final String SAVED_REQUEST_KEY = "savedRequest";
	
    /**
     * Constant representing the HTTP 'GET' request method, equal to <code>GET</code>.
     */
    public static final String GET_METHOD = "GET";

    /**
     * Constant representing the HTTP 'POST' request method, equal to <code>POST</code>.
     */
    public static final String POST_METHOD = "POST";
	
	/**
	 * 
	 * <p>向客户端输出json</p>
	 * @param response
	 * @param result
	 * @author 陶焕(13294175866)
	 */
	public static void returnJson(HttpServletResponse response,Object result){
		try {
			response.setContentType("text/html;charset=UTF-8");
			if(result instanceof String){
				response.getWriter().write((String)result);
			}else{
				response.getWriter().write(JsonBuilder.toJson(result));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			log.error("向客户端输出Json出错:{}",e);
		}
	}
	
	/**
	 * 
	 * <p>返回文件或者文件流</p>
	 * @param response
	 * @param result
	 * @author 陶焕(13294175866)
	 */
	public static void returnFile(HttpServletRequest request,HttpServletResponse response,String contentType,File file,boolean isDownload){
		try {
		String filename = file.getName();//获取文件名称，在转化为子串
		String userAgent = request.getHeader("User-Agent");  
		log.info("userAgent:{}", userAgent);
		if (null != userAgent && -1 != userAgent.indexOf("MSIE") || null != userAgent  
                && -1 != userAgent.indexOf("Trident")) {// ie  
			filename = java.net.URLEncoder.encode(filename, "UTF-8");  
        } else if (null != userAgent && -1 != userAgent.indexOf("Mozilla")) {// 火狐,chrome等  
        	filename = new String(filename.getBytes("UTF-8"), "iso-8859-1");  
        }  
        
		if(isDownload){
			//attachment --- 作为附件下载
			//inline --- 在线打开
			response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", filename)); // 文件名外的双引号处理firefox的空格截断问题
			//response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));  
		}
			returnStream(response,contentType,new FileInputStream(file));
		} catch (FileNotFoundException | UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			log.error("向客户端输出流出错:{}",e);
		}
	}
	
	/**
	 * 
	 * <p>向客户端输出流</p>
	 * @param response
	 * @param in
	 * @author 陶焕(13294175866)
	 */
	public static void returnStream(HttpServletResponse response,String contentType,InputStream in){
		OutputStream out = null ;  
		try {
			int len = 0;
			byte buf[] = new byte[4096];// 缓存作用
			response.setContentType(contentType);
			out = response.getOutputStream();// 输出流
			while ((len = in.read(buf)) > 0){ // 切忌这后面不能加 分号 ”;“
				out.write(buf, 0, len);// 向客户端输出，实际是把数据存放在response中，然后web服务器再去response中读取
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			log.error("打开输出流出错:{}",e);
		} finally {
			IOUtils.closeQuietly(in);
			IOUtils.closeQuietly(out);
		}
	}
	
	public static CommonResult<Object> returnSuccessMsg(String msg){
		return returnSuccessMsg(msg,null);
	}
	
	public static CommonResult<Object> returnSuccessMsg(String msg,Object data){
		CommonResult<Object> result = new CommonResult<Object>(CommonResult.successCode);
		result.setMessage(msg);
		result.setData(data);
		return result;
	}
	
	public static CommonResult<String> returnFailureMsg(int failureCode,String msg){
		CommonResult<String> result = new CommonResult<String>(failureCode);
		result.setMessage(msg);
		return result;
	}
	
	/**
	 * 
	 * <p>获取项目的ContextPath,以"/"结尾</p>
	 * @param request
	 * @return
	 * @author 陶焕(13294175866)
	 */
	public static String getContextPath(HttpServletRequest request){
		String contextPath = request.getContextPath();
		if(!contextPath.endsWith("/")){
			contextPath +="/";
		}
        return contextPath;
    }

	/**
	 * 
	 * <p>获取项目的真实文件路径,以"/"结尾</p>
	 * @param request
	 * @return
	 * @author 陶焕(13294175866)
	 */
    public static String getRootRealPath(HttpServletRequest request){
    	String rootPath = request.getSession().getServletContext().getRealPath("/");
    	rootPath = rootPath.replace("\\", "/");
    	if(!rootPath.endsWith("/")){
    		rootPath +="/";
		}
        return rootPath;
    }
    
    public static void saveRequest(HttpServletRequest request) {
        HttpSession session = request.getSession();
        SavedRequest savedRequest = new SavedRequest(request);
        session.setAttribute(SAVED_REQUEST_KEY, savedRequest);
    }

    public static SavedRequest getAndClearSavedRequest(HttpServletRequest request) {
        SavedRequest savedRequest = getSavedRequest(request);
        if (savedRequest != null) {
        	HttpSession session = request.getSession();
            session.removeAttribute(SAVED_REQUEST_KEY);
        }
        return savedRequest;
    }

    public static SavedRequest getSavedRequest(HttpServletRequest request) {
        SavedRequest savedRequest = null;
        HttpSession session = request.getSession();
        if (session != null) {
            savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);
        }
        return savedRequest;
    }

    /**
     * Redirects the to the request url from a previously
     * {@link #saveRequest(javax.servlet.HttpServletRequest) saved} request, or if there is no saved request, redirects the
     * end user to the specified {@code fallbackUrl}.  If there is no saved request or fallback url, this method
     * throws an {@link IllegalStateException}.
     * <p/>
     * This method is primarily used to support a common login scenario - if an unauthenticated user accesses a
     * page that requires authentication, it is expected that request is
     * {@link #saveRequest(javax.servlet.HttpServletRequest) saved} first and then redirected to the login page. Then,
     * after a successful login, this method can be called to redirect them back to their originally requested URL, a
     * nice usability feature.
     *
     * @param request     the incoming request
     * @param response    the outgoing response
     * @param fallbackUrl the fallback url to redirect to if there is no saved request available.
     * @throws IllegalStateException if there is no saved request and the {@code fallbackUrl} is {@code null}.
     * @throws IOException           if there is an error redirecting
     * @since 1.0
     */
    public static void redirectToSavedRequest(HttpServletRequest request, HttpServletResponse response, String fallbackUrl)
            throws IOException {
        String successUrl = null;
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
        if (savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(GET_METHOD)) {
            successUrl = savedRequest.getRequestUrl();
        }

        if (successUrl == null) {
            successUrl = fallbackUrl;
        }

        if (successUrl == null) {
            throw new IllegalStateException("Success URL not available via saved request or via the " +
                    "successUrlFallback method parameter. One of these must be non-null for " +
                    "issueSuccessRedirect() to work.");
        }
        response.sendRedirect(successUrl);
    }
    
	
}
